home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
windownt
/
embh32.zip
/
EMBH.C
next >
Wrap
C/C++ Source or Header
|
1993-09-16
|
25KB
|
726 lines
/****************************************************************************
* *
* EMBH: Embedded windows for Windows Help projects. *
* Windows NT Version *
* 2/18/93 by Mark Gamber *
* *
****************************************************************************/
#include "windows.h"
#include "mmsystem.h"
#include "embh.h"
HANDLE hInst;
int WinDoc;
char *BULLET = "BULLET"; // Class names for windows
char *ARROW = "ARROW";
char *MODEM = "MODEM";
char *POINTER = "POINTER";
char *WSIZE = "SIZE";
char *XSIZE = "XSIZE";
char *YSIZE = "YSIZE";
char *FILES = "FILES";
/****************************************************************************
* *
* LibMain() - Entry point to DLL. Registers windows classes. *
* *
****************************************************************************/
BOOL WINAPI DLLEntryPoint( HANDLE hDll, DWORD dwReason, LPVOID lpReserved )
{
WNDCLASS wc;
hInst = hDll;
wc.style = CS_GLOBALCLASS;
wc.lpfnWndProc = BulletWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = BULLET_EXTRA_BYTES;
wc.hIcon = NULL;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject( NULL_BRUSH );
wc.hInstance = hDll;
wc.lpszMenuName = NULL;
wc.lpszClassName = BULLET;
RegisterClass( &wc );
wc.style = CS_GLOBALCLASS;
wc.lpfnWndProc = ArrowWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = ARROW_EXTRA_BYTES;
wc.hIcon = NULL;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject( NULL_BRUSH );
wc.hInstance = hDll;
wc.lpszMenuName = NULL;
wc.lpszClassName = ARROW;
RegisterClass( &wc );
wc.style = CS_GLOBALCLASS;
wc.lpfnWndProc = ModemWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = MODEM_EXTRA_BYTES;
wc.hIcon = NULL;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject( NULL_BRUSH );
wc.hInstance = hDll;
wc.lpszMenuName = NULL;
wc.lpszClassName = MODEM;
RegisterClass( &wc );
wc.style = CS_GLOBALCLASS;
wc.lpfnWndProc = RightPointerWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = RPOINTER_EXTRA_BYTES;
wc.hIcon = NULL;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject( NULL_BRUSH );
wc.hInstance = hDll;
wc.lpszMenuName = NULL;
wc.lpszClassName = POINTER;
RegisterClass( &wc );
return( TRUE );
}
/****************************************************************************
* *
* Bullet window process *
* *
****************************************************************************/
LONG WINAPI BulletWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case 0x706B: // Custom message from Winhelp asking
((LPPOINT)lParam)->x = 10; // for embedded window size. Fill in
((LPPOINT)lParam)->y = 10; // Point structure tellng it 10x10
return( 1L );
case WM_CREATE:
{
LPCREATESTRUCT lpCs = (LPCREATESTRUCT)lParam;
LPEWDATA lpEw;
WORD i;
lpEw = (LPEWDATA)lpCs->lpCreateParams; // Get EWDATA from Struct
i = 0;
if( lstrlen( lpEw->szAuthorData ) ) // If there's a parameter
{
if( lpEw->szAuthorData[ 0 ] == 'F' ) // Forward cycling
SetWindowLong( hWnd, BULLET_CYCLING, 1 );
else
if( lpEw->szAuthorData[ 0 ] == 'B' ) // Or backward cycling
SetWindowLong( hWnd, BULLET_CYCLING, 2 );
else
SetWindowLong( hWnd, BULLET_CYCLING, 0 ); // Or no cycling
if( lpEw->szAuthorData[ 1 ] == '1' ) // Determine what colors
i |= 1; // to use by looking
if( lpEw->szAuthorData[ 2 ] == '1' ) // at next three chars
i |= 2;
if( lpEw->szAuthorData[ 3 ] == '1' )
i |= 4;
}
SetWindowLong( hWnd, BULLET_COLOR, i ); // Save color specifier
SetWindowLong( hWnd, BULLET_BRIGHT, 255 ); // Save brightness value
if( GetWindowLong( hWnd, BULLET_CYCLING ) ) // If cycling is on
SetTimer( hWnd, 1, 100, NULL ); // Start a system timer
break;
}
case WM_TIMER: // Called if cycling enabled
{
WORD i, r, g, b;
DWORD dwColor;
HDC hDC;
HBRUSH hBrush;
i = GetWindowLong( hWnd, BULLET_COLOR ); // Get current color spec
r = g = b = 0;
if( i & 1 )
r = GetWindowLong( hWnd, BULLET_BRIGHT );
if( i & 2 )
g = GetWindowLong( hWnd, BULLET_BRIGHT );
if( i & 4 )
b = GetWindowLong( hWnd, BULLET_BRIGHT );
// Create a brush using color
hBrush = CreateSolidBrush( RGB( r, g, b ) );
hDC = GetDC( hWnd );
SelectObject( hDC, GetStockObject( BLACK_PEN ) );
SelectObject( hDC, hBrush );
Ellipse( hDC, 0, 0, 10, 10 ); // Draw the bullet
ReleaseDC( hWnd, hDC );
DeleteObject( hBrush );
if( GetWindowLong( hWnd, BULLET_CYCLING ) == 1 ) // If forward...
{
i = GetWindowLong( hWnd, BULLET_BRIGHT ); // Get lum. value
if( i == 15 ) // If already at the bottom
i = 255; // Put back at the top
else
i -= 16; // Otherwise, knock off 16
}
else
{
i = GetWindowLong( hWnd, BULLET_BRIGHT ); // If backwards...
if( i == 255 ) // If already at the top
i = 0; // Plug in a zero
else
i += 16; // Otherwise, add 16
}
SetWindowLong( hWnd, BULLET_BRIGHT, i ); // Save new value
break;
}
case WM_PAINT: // Important mostly for non-cycling windows
{
PAINTSTRUCT Ps;
HDC hDC;
HBRUSH hBrush;
WORD i, r, g, b;
hDC = BeginPaint( hWnd, &Ps );
i = GetWindowLong( hWnd, BULLET_COLOR ); // Get color specifier
r = g = b = 0;
if( i & 1 ) // If color bit is set, turn full on
r = 255;
if( i & 2 )
g = 255;
if( i & 4 )
b = 255;
// Make a brush from current color
hBrush = CreateSolidBrush( RGB( r, g, b ) );
SelectObject( hDC, GetStockObject( BLACK_PEN ) );
SelectObject( hDC, hBrush );
Ellipse( hDC, 0, 0, 10, 10 ); // Draw bullet and exit
EndPaint( hWnd, &Ps );
DeleteObject( hBrush );
return( TRUE );
}
case WM_DESTROY:
if( GetWindowLong( hWnd, BULLET_CYCLING ) )
KillTimer( hWnd, 1 ); // before allowing window to go
break;
default:
return( DefWindowProc( hWnd, msg, wParam, lParam ) );
}
return( FALSE );
}
/****************************************************************************
* *
* ARROW window proc. Basically same as BULLET *
* *
****************************************************************************/
LONG WINAPI ArrowWndProc( HWND hWnd, UINT msg, UINT wParam, LONG lParam )
{
switch( msg )
{
case 0x706B: // Size request message from Winhelp
((LPPOINT)lParam)->x = 21;
((LPPOINT)lParam)->y = 11; // This one is 21x11
return( 1L );
case WM_CREATE:
{
LPCREATESTRUCT lpCs = (LPCREATESTRUCT)lParam;
LPEWDATA lpEw;
WORD i;
lpEw = (LPEWDATA)lpCs->lpCreateParams;
i = 0;
if( lstrlen( lpEw->szAuthorData ) )
{
if( lpEw->szAuthorData[ 0 ] == 'F' ) // Pick apart color values
SetWindowLong( hWnd, ARROW_CYCLING, 1 );
else
if( lpEw->szAuthorData[ 0 ] == 'B' )
SetWindowLong( hWnd, ARROW_CYCLING, 2 );
else
SetWindowLong( hWnd, ARROW_CYCLING, 0 );
if( lpEw->szAuthorData[ 1 ] == '1' )
i |= 1;
if( lpEw->szAuthorData[ 2 ] == '1' )
i |= 2;
if( lpEw->szAuthorData[ 3 ] == '1' )
i |= 4;
}
SetWindowLong( hWnd, ARROW_COLOR, i );
SetWindowLong( hWnd, ARROW_BRIGHT, 15 );
if( GetWindowLong( hWnd, ARROW_CYCLING ) ) // If cycling enabled
SetTimer( hWnd, 1, 100, NULL ); // Obtain a timer
break;
}
case WM_TIMER:
{
WORD i, r, g, b;
DWORD dwColor;
HDC hDC;
HBRUSH hBrush;
i = GetWindowLong( hWnd, ARROW_COLOR ); // Get color spec.
r = g = b = 0;
if( i & 1 )
r = GetWindowLong( hWnd, ARROW_BRIGHT ) * 16; // I screwed up and forgot
if( i & 2 ) // to be consistant, so this
g = GetWindowLong( hWnd, ARROW_BRIGHT ) * 16; // proc takes the luminence
if( i & 4 ) // from 1 to 16 and multiplies
b = GetWindowLong( hWnd, ARROW_BRIGHT ) * 16; // by 16 for real lum value
hDC = GetDC( hWnd );
hBrush = CreateSolidBrush( RGB( r, g, b ) );
SelectObject( hDC, GetStockObject( BLACK_PEN ) );
SelectObject( hDC, hBrush );
DrawArrow( hDC ); // Draw the arrow (below)
ReleaseDC( hWnd, hDC );
DeleteObject( hBrush );
i = GetWindowLong( hWnd, ARROW_BRIGHT );
if( GetWindowWord( hWnd, ARROW_CYCLING ) == 1 ) // If moving forward
{
if( i == 0 ) // Subtract one, wrapping if needed
i = 15;
else
--i;
}
else
{
if( i == 15 ) // Backwards, add one and wrap
i = 0;
else
++i;
}
SetWindowLong( hWnd, ARROW_BRIGHT, i ); // Save current lum value and exit
break;
}
case WM_PAINT: // Repaint, mostly for static windows
{
PAINTSTRUCT Ps;
HDC hDC;
HBRUSH hBrush;
WORD i, r, g, b;
hDC = BeginPaint( hWnd, &Ps );
i = GetWindowLong( hWnd, ARROW_COLOR );
r = g = b = 0;
if( i & 1 ) // If color is enabled, turn on full
r = 255;
if( i & 2 )
g = 255;
if( i & 4 )
b = 255;
SelectObject( hDC, GetStockObject( BLACK_PEN ) );
hBrush = CreateSolidBrush( RGB( r, g, b ) );
SelectObject( hDC, hBrush );
DrawArrow( hDC ); // Draw the arrow and exit
EndPaint( hWnd, &Ps );
DeleteObject( hBrush );
return( TRUE );
}
case WM_DESTROY:
if( GetWindowWord( hWnd, ARROW_CYCLING ) ) // Kill the timer before window
KillTimer( hWnd, 1 );
break;
default:
return( DefWindowProc( hWnd, msg, wParam, lParam ) );
}
return( FALSE );
}
void DrawArrow( HDC hDC )
{
POINT Pt[ 10 ];
Pt[ 0 ].x = 0; // Fill in array of points describing arrow
Pt[ 0 ].y = 3;
Pt[ 1 ].x = 14;
Pt[ 1 ].y = 3;
Pt[ 2 ].x = 14;
Pt[ 2 ].y = 0;
Pt[ 3 ].x = 15; // Big list, huh?
Pt[ 3 ].y = 0;
Pt[ 4 ].x = 20;
Pt[ 4 ].y = 5;
Pt[ 5 ].x = 15;
Pt[ 5 ].y = 10;
Pt[ 6 ].x = 14;
Pt[ 6 ].y = 10;
Pt[ 7 ].x = 14;
Pt[ 7 ].y = 7;
Pt[ 8 ].x = 0; // Maybe not as bad as a paint program but
Pt[ 8 ].y = 7;
Pt[ 9 ].x = 0; // Still a pain in the ass
Pt[ 9 ].y = 3;
Polygon( hDC, (LPPOINT)Pt, 10 ); // (whew)....draw shape
}
/****************************************************************************
* *
* MODEM window proc. This one is *real* easy *
* *
****************************************************************************/
LONG WINAPI ModemWndProc( HWND hWnd, UINT msg, UINT wParam, LONG lParam )
{
switch( msg )
{
case 0x706B: // Size request from Winhelp
((LPPOINT)lParam)->x = 31; // Modem is 31x11
((LPPOINT)lParam)->y = 11;
return( 1L );
case WM_CREATE:
SetWindowLong( hWnd, MODEM_BLINK, 0 ); // Initialize blink status
SetTimer( hWnd, 1, 100, NULL ); // Enable timer and we're off
break;
case WM_TIMER:
{
HDC hDC;
HDC mDC;
HBITMAP hBmp;
hDC = GetDC( hWnd );
mDC = CreateCompatibleDC( hDC );
// Load bitmap depending on
if( ! GetWindowLong( hWnd, MODEM_BLINK ) ) // blink status
hBmp = LoadBitmap( hInst, MAKEINTRESOURCE( 100 ) );
else
hBmp = LoadBitmap( hInst, MAKEINTRESOURCE( 101 ) );
SelectObject( mDC, hBmp );
// Draw the modem
BitBlt( hDC, 0, 0, 31, 11, mDC, 0, 0, SRCCOPY );
DeleteDC( mDC );
DeleteObject( hBmp );
ReleaseDC( hWnd, hDC );
if( GetWindowLong( hWnd, MODEM_BLINK ) ) // Toggle blink setting
SetWindowLong( hWnd, MODEM_BLINK, 0 );
else
SetWindowLong( hWnd, MODEM_BLINK, 1 ); // Told ya it was easy
break;
}
case WM_DESTROY:
KillTimer( hWnd, 1 ); // Make timer die before window does
break;
default:
return( DefWindowProc( hWnd, msg, wParam, lParam ) );
}
return( FALSE );
}
/****************************************************************************
* *
* Right pointer - Color is specified at creation and may be changed *
* *
****************************************************************************/
LONG WINAPI RightPointerWndProc( HWND hWnd, UINT msg, UINT wParam, LONG lParam )
{
switch( msg )
{
case 0x706B:
((LPPOINT)lParam)->x = 11;
((LPPOINT)lParam)->y = 11;
return( 1L );
case WM_CREATE:
{
LPCREATESTRUCT lpCs = (LPCREATESTRUCT)lParam;
LPEWDATA lpEw;
int i, j;
lpEw = (LPEWDATA)lpCs->lpCreateParams;
i = lstrlen( lpEw->szAuthorData );
if( ! i )
{
DestroyWindow( hWnd );
return( TRUE );
}
for( j = 0; j < i; j++ ) // Loop through string looking
if( lpEw->szAuthorData[ j ] == ':' ) // for name/color separator
break; // If found, break loop
if( i != j ) // If title and color included
{
lpEw->szAuthorData[ j ] = '\0'; // Separate with NULL
SetWindowText( hWnd, lpEw->szAuthorData ); // Apply title
i = 0;
if( lpEw->szAuthorData[ j + 1 ] == '1' ) // Use RED?
i += 1;
if( lpEw->szAuthorData[ j + 2 ] == '1' ) // Use GREEN?
i += 2;
if( lpEw->szAuthorData[ j + 3 ] == '1' ) // Use BLUE?
i += 4;
SetWindowLong( hWnd, RPOINTER_COLOR, i );
}
else
{
SetWindowText( hWnd, lpEw->szAuthorData ); // No initial color
SetWindowWord( hWnd, RPOINTER_COLOR, 7 ); // Default to white
}
break;
}
case WM_PAINT:
{
PAINTSTRUCT Ps;
HDC hDC;
HBRUSH hBrush;
int r, g, b, t;
POINT Pt[ 4 ];
hDC = BeginPaint( hWnd, &Ps );
t = GetWindowLong( hWnd, RPOINTER_COLOR ); // Get color bits
r = g = b = 0;
if( t & 1 )
r = 255;
if( t & 2 )
g = 255;
if( t & 4 )
b = 255;
hBrush = CreateSolidBrush( RGB( r, g, b ) );
SelectObject( hDC, hBrush );
SelectObject( hDC, GetStockObject( BLACK_PEN ) );
Pt[ 0 ].x = 0; // Initialize point array
Pt[ 0 ].y = 0;
Pt[ 1 ].x = 10;
Pt[ 1 ].y = 5;
Pt[ 2 ].x = 0;
Pt[ 2 ].y = 10;
Pt[ 3 ].x = 0;
Pt[ 3 ].y = 0;
Polygon( hDC, (LPPOINT)Pt, 4 ); // Draw right pointer
EndPaint( hWnd, &Ps );
DeleteObject( hBrush );
return( TRUE );
}
case WM_USER + 1024:
{
SetWindowLong( hWnd, RPOINTER_COLOR, wParam ); // Color passed in wParam
InvalidateRect( hWnd, NULL, TRUE ); // Redraw with new color
return( TRUE );
}
default:
return( DefWindowProc( hWnd, msg, wParam, lParam ) );
}
return( FALSE );
}
/****************************************************************************
* *
* SetRightPointerColor() - Call as a Winhelp macro *
* *
****************************************************************************/
BOOL CALLBACK SRPC( LPSTR lpWinHelp, LPSTR lpTitle, LPSTR lpColorBits )
{
return( SetRightPointerColor( lpWinHelp, lpTitle, lpColorBits ) );
}
BOOL CALLBACK SetRightPointerColor( LPSTR lpWinHelp, LPSTR lpTitle,
LPSTR lpColorBits )
{
FINDWIN Fw;
HWND hWnd;
if( ! lpTitle || ! lpColorBits || ! lpWinHelp ) // If parameter is NULL
return( FALSE ); // exit now
if( ! lstrlen( lpTitle ) || lstrlen( lpColorBits ) < 3 )
return( FALSE ); // No invalid ones, either
hWnd = FindWindow( NULL, lpWinHelp ); // Find Winhelp window
if( ! hWnd )
return( FALSE ); // If can't be found, exit
Fw.lpChildName = lpTitle; // Pass child title and color to
Fw.lpColorBits = lpColorBits; // enum proc using structure
Fw.Operation = 0;
EnumChildWindows( hWnd, FindRPntProc, (LONG)(FINDWIN *)&Fw );
return( TRUE );
}
/****************************************************************************
* *
* Used to find correct right pointer window to accept new color *
* *
****************************************************************************/
BOOL CALLBACK FindRPntProc( HWND hWnd, LONG lParam )
{
FINDWIN *lpFw = (FINDWIN *)lParam;
char str[ 30 ];
int t;
if( ! hWnd )
return( FALSE );
GetWindowText( hWnd, str, 30 ); // Get title of child window
if( ! lstrcmpi( str, lpFw->lpChildName ) ) // If this is the one we want
{
if( ! lpFw->Operation )
{
t = 0;
if( *lpFw->lpColorBits == '1' )
t += 1;
if( *( lpFw->lpColorBits + 1 ) == '1' )
t += 2;
if( *( lpFw->lpColorBits + 2 ) == '1' )
t += 4;
// Change color via a message
PostMessage( hWnd, WM_USER + 1024, t, 0 );
return( FALSE );
}
}
return( TRUE );
}
/****************************************************************************
* *
* Center a secondary window with respect to the main window *
* *
****************************************************************************/
BOOL CALLBACK CenterWindow( LPSTR lpWinHelp, LPSTR lpChild )
{
HWND hHelp;
HWND hChild;
int x, y;
RECT pRect;
RECT cRect;
if( ! lpWinHelp || ! lpChild ) // If either pointer is bad, exit
return( FALSE );
// If either string is zero length, exit
if( ! lstrlen( lpWinHelp ) || ! lstrlen( lpChild ) )
return( FALSE );
hHelp = FindWindow( NULL, lpWinHelp ); // Find main help window
if( ! hHelp )
return( FALSE );
hChild = FindWindow( NULL, lpChild ); // Find secondary window
if( ! hChild )
return( FALSE );
GetWindowRect( hHelp, &pRect ); // Get screen coordinates of main
GetClientRect( hChild, &cRect ); // Get size of secondary window
// Figure out where "centered" is
x = pRect.left + ( ( pRect.right - pRect.left - cRect.right ) >> 1 );
y = pRect.top + ( ( pRect.bottom - pRect.top - cRect.bottom ) >> 1 );
// Reposition window and exit
SetWindowPos( hChild, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE );
return( TRUE );
}
/****************************************************************************
* *
* Align secondary window to main window's right, center vertically *
* *
****************************************************************************/
BOOL CALLBACK RightAlignWindow( LPSTR lpWinHelp, LPSTR lpChild )
{
HWND hHelp;
HWND hChild;
int x, y;
RECT pRect;
RECT cRect;
if( ! lpWinHelp || ! lpChild ) // If either pointer is bad, exit
return( FALSE );
// If either string is zero length, exit
if( ! lstrlen( lpWinHelp ) || ! lstrlen( lpChild ) )
return( FALSE );
hHelp = FindWindow( NULL, lpWinHelp ); // Find main window or exit
if( ! hHelp )
return( FALSE );
hChild = FindWindow( NULL, lpChild ); // Find secondary window or exit
if( ! hChild )
return( FALSE );
GetWindowRect( hHelp, &pRect ); // Get screen coordinates of main
GetClientRect( hChild, &cRect ); // Get client size of secondary
// Right align secoondary
x = pRect.right - cRect.right - ( GetSystemMetrics( SM_CXFRAME ) << 1 ) - 4;
y = pRect.top + ( ( pRect.bottom - pRect.top - cRect.bottom ) >> 1 );
// Reposition and exit
SetWindowPos( hChild, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE );
return( TRUE );
}